Git Troubleshooting Guide
This guide covers common Git issues you might encounter when working with GitHub repositories, with detailed solutions and best practices to prevent future problems.
Divergent Branches Error
One of the most common issues developers face is the "divergent branches" error when trying to pull from a remote repository.
Understanding the Error
When you see this error message:
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
This happens when:
- Your local branch has commits that aren't on the remote branch
- The remote branch has commits that aren't on your local branch
- Git doesn't know how you want to combine these divergent histories
- Immediate Solution
- Understanding Options
- Prevention
Quick Fix for the Error:
If you're on the wrong branch (common cause):
# Check which branch you're on
git branch
# Switch to main branch
git checkout main
# Now pull should work
git pull origin main
If you're on the correct branch:
# Option 1: Use merge strategy (preserves branch history)
git config pull.rebase false
git pull
# Option 2: Use rebase strategy (creates linear history)
git config pull.rebase true
git pull
# Option 3: Use fast-forward only (fails if not possible)
git config pull.ff only
git pull
The Three Strategies Explained:
1. Merge (pull.rebase false)
- Creates a merge commit that combines the histories
- Preserves the exact history of both branches
- Results in a more complex but complete history
- Use when: You want to preserve all commit history
2. Rebase (pull.rebase true)
- Replays your local commits on top of the remote commits
- Creates a linear, cleaner history
- Rewrites commit hashes for your local commits
- Use when: You want a clean, linear history
3. Fast-Forward Only (pull.ff only)
- Only updates if your branch can be fast-forwarded
- Fails if there are divergent changes
- Prevents accidental merges
- Use when: You want to ensure no merge commits are created
Preventing Divergent Branches:
1. Set Global Git Configuration:
# Set your preferred default strategy
git config --global pull.rebase false # or true, or ff
2. Workflow Best Practices:
- Always pull before starting new work
- Commit your changes before pulling
- Use feature branches for new development
- Keep main/master branch clean
3. Regular Synchronization:
# Daily workflow
git checkout main
git pull origin main
git checkout your-feature-branch
git rebase main # or merge main
Common Git Issues and Solutions
- Authentication Issues
- Merge Conflicts
- Push/Pull Problems
- Branch Issues
Problem: Authentication failed when pushing/pulling
Symptoms:
remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/...'
Solutions:
1. Use Personal Access Token (Recommended):
# Generate token at: https://github.com/settings/tokens
# Use token as password when prompted
git push origin main
2. Use GitHub CLI:
# Install GitHub CLI: https://cli.github.com/
gh auth login
# Follow prompts to authenticate
3. Set Up SSH Keys:
# Generate SSH key
ssh-keygen -t ed25519 -C "[email protected]"
# Add to SSH agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# Add public key to GitHub account
cat ~/.ssh/id_ed25519.pub
# Copy output and add to GitHub Settings > SSH Keys
# Test connection
ssh -T [email protected]
4. Update Remote URL to Use SSH:
# Change from HTTPS to SSH
git remote set-url origin [email protected]:username/repository.git
Problem: Merge conflicts during pull or merge
Symptoms:
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
Automatic merge failed; fix conflicts and then commit the result.
Step-by-Step Resolution:
1. Identify Conflicted Files:
git status
# Look for files marked as "both modified"
2. Edit Conflicted Files:
<<<<<<< HEAD
Your local changes
=======
Remote changes
>>>>>>> branch-name
3. Resolve Conflicts:
- Remove conflict markers (
<<<<<<<
,=======
,>>>>>>>
) - Keep the code you want
- Save the file
4. Complete the Merge:
# Stage resolved files
git add filename
# Commit the merge
git commit -m "Resolve merge conflict in filename"
Tools for Easier Resolution:
# Use Git's built-in merge tool
git mergetool
# Or configure your preferred editor
git config --global merge.tool vimdiff # or code, etc.
Problem: Cannot push or pull from repository
Common Causes and Solutions:
1. Repository URL Issues:
# Check current remote URL
git remote -v
# Update if incorrect
git remote set-url origin https://github.com/username/repo.git
2. Branch Tracking Issues:
# Set upstream branch
git push -u origin branch-name
# Or set tracking for existing branch
git branch --set-upstream-to=origin/main main
3. Large File Issues:
# If files are too large (>100MB)
# Use Git LFS
git lfs install
git lfs track "*.large-extension"
git add .gitattributes
git commit -m "Add LFS tracking"
4. Network/Connectivity Issues:
# Test connectivity
ping github.com
# Try different protocol
git remote set-url origin [email protected]:username/repo.git
Problem: Branch-related issues
Cannot Switch Branches:
# If you have uncommitted changes
git stash
git checkout other-branch
git stash pop # Apply changes to new branch
Branch Not Showing Up:
# Fetch all remote branches
git fetch --all
# List all branches (including remote)
git branch -a
# Create local branch tracking remote
git checkout -b local-branch-name origin/remote-branch-name
Accidental Commits on Wrong Branch:
# Move last commit to different branch
git checkout correct-branch
git cherry-pick wrong-branch
git checkout wrong-branch
git reset --hard HEAD~1
Delete Branches:
# Delete local branch (must not be current branch)
git branch -d branch-name
# Force delete local branch
git branch -D branch-name
# Delete remote branch
git push origin --delete branch-name
Advanced Troubleshooting
- History Issues
- Repository Corruption
- Performance Issues
Fixing Commit History Issues:
Undo Last Commit (Keep Changes):
git reset --soft HEAD~1
Undo Last Commit (Discard Changes):
git reset --hard HEAD~1
Amend Last Commit:
# Change commit message
git commit --amend -m "New message"
# Add files to last commit
git add forgotten-file
git commit --amend --no-edit
Revert a Commit (Safe for Shared History):
git revert commit-hash
Interactive Rebase (Rewrite History):
# Rebase last 3 commits
git rebase -i HEAD~3
# Use only on commits not pushed to shared repositories
Repository Corruption Issues:
Verify Repository Integrity:
git fsck --full
Fix Corrupted Objects:
# Garbage collection and cleanup
git gc --aggressive
# Prune unreachable objects
git prune
Recovery from Backup:
# If corruption is severe, re-clone
cd ..
rm -rf corrupted-repo
git clone https://github.com/username/repo.git
Recover Lost Commits:
# Find lost commits
git reflog
# Recover specific commit
git checkout lost-commit-hash
git checkout -b recovery-branch
Performance Optimization:
Large Repository Issues:
# Shallow clone for faster downloads
git clone --depth 1 https://github.com/username/repo.git
# Partial clone (Git 2.19+)
git clone --filter=blob:none https://github.com/username/repo.git
Reduce Repository Size:
# Clean up unnecessary files
git gc --aggressive --prune=now
# Remove large files from history (use with caution)
git filter-branch --tree-filter 'rm -f large-file' HEAD
Optimize Network Operations:
# Use SSH instead of HTTPS for better performance
git remote set-url origin [email protected]:username/repo.git
# Configure Git for better performance
git config --global core.preloadindex true
git config --global core.fscache true
git config --global gc.auto 256
Git Configuration Best Practices
- Global Configuration
- Repository-Specific
- Aliases & Shortcuts
Essential Global Git Settings:
# User identity
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
# Default branch name
git config --global init.defaultBranch main
# Pull strategy (choose one)
git config --global pull.rebase false # merge
# git config --global pull.rebase true # rebase
# git config --global pull.ff only # fast-forward only
# Push behavior
git config --global push.default simple
# Editor for commit messages
git config --global core.editor "code --wait" # VS Code
# git config --global core.editor "vim" # Vim
# Diff and merge tools
git config --global diff.tool vscode
git config --global merge.tool vscode
# Auto-correct typos
git config --global help.autocorrect 1
# Better diff algorithm
git config --global diff.algorithm patience
Repository-Specific Settings:
# Different user for work repositories
git config user.email "[email protected]"
# Repository-specific pull strategy
git config pull.rebase true
# Custom hooks directory
git config core.hooksPath .githooks
# Ignore file permissions (useful on Windows)
git config core.filemode false
# Line ending handling
git config core.autocrlf true # Windows
git config core.autocrlf input # macOS/Linux
Useful Git Aliases:
# Status shortcuts
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
# Advanced aliases
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual '!gitk'
# Pretty log formats
git config --global alias.lg "log --oneline --decorate --graph"
git config --global alias.lga "log --oneline --decorate --graph --all"
# Useful shortcuts
git config --global alias.amend 'commit --amend --no-edit'
git config --global alias.oops 'reset --soft HEAD~1'
git config --global alias.sync '!git fetch && git checkout main && git pull'
Using Aliases:
# Instead of 'git status'
git st
# Instead of 'git log --oneline --decorate --graph'
git lg
# Custom sync command
git sync
Emergency Git Commands
When things go wrong, these commands can help recover:
# See what you did recently
git reflog
# Undo almost anything
git reset --hard HEAD~1
# Save work in progress
git stash
# Recover deleted branch
git checkout -b recovered-branch commit-hash
# Force push (use with extreme caution)
git push --force-with-lease
# Start over completely
git reset --hard origin/main
Warning: Commands like reset --hard
and push --force
can permanently delete work. Always make sure you have backups or that the work isn't needed before using destructive commands.